home *** CD-ROM | disk | FTP | other *** search
/ Aminet 12 / Aminet 12 (1996)(GTI - Schatztruhe)[!][Jun 1996].iso / Aminet / util / cli / Splat.lha / Splat.e < prev   
Text File  |  1996-02-13  |  11KB  |  354 lines

  1. -> SPLAT.e v1.0    NeVeZ' file splitter!
  2. -> -------------------------------------
  3. -> 11/4/96 by Stephen Cantini
  4. -> -------------------------------------
  5.  
  6. MODULE 'dos/dos','dos/rdargs'
  7.  
  8. ENUM OK,ER_MEM,ER_ARGS,ER_LENGTH,ER_IO,ER_BREAK,ER_INT,ER_UNIMP
  9.  
  10. CONST EOF=-1
  11.  
  12. DEF a,z,opts[15]:ARRAY OF LONG,name[1024]:STRING,search[1024]:STRING
  13.  
  14. PROC main() HANDLE
  15.     DEF rda=NIL:PTR TO rdargs,flag,flen,fhandle=NIL,fout=NIL,size,count,
  16.         er,mem=NIL,buflen,blockleft,eof,eob,offset,lines,sflag,max
  17.  
  18.     a:='$VER: Splat 1.0 (11.4.96) (c) Copyright Stephen Cantini'
  19.  
  20.     -> SET extended help STRING
  21.  
  22.     rda:=AllocDosObject(DOS_RDARGS,NIL)
  23.     IF rda=NIL THEN Raise(ER_MEM)
  24.     rda.exthelp:='Splat V1.0 (c) Stephen Cantini\n\n'+
  25.                  'FILE/A = The file to be splitted\n'+
  26.                  'S=SEARCH/K = String to search for.\nSIZE/N = Split at this number of bytes.\nK/S = Size is expressed in kbytes.\n'+
  27.                  'LINES/S = Size is expressed in lines.\nTO/K = Optional destination directory/filenames (DEFAULT:input file''s).\nR=RECURSIVE/S = Split EVERY size bytes/k/lines/search.\n'+
  28.                  'QUIET/S = Sshhhh!! :)\nBUF=BUFFER/K/N = I/O buffer size in kbytes.\nPARTS/S = Divide in SIZE parts.\nNOCUT/S = Do not trunc text lines.\n'+
  29.                  'QUICK/S = Output JUST the number of files created.\nNOCASE/S = Make string search case insensitive.\nDOWILD/S = Allow jolly character "?" in search string.\n'+
  30.                  'MAX/K/N = Max number of files to create.\n'
  31.  
  32.     -> Read command arguments
  33.  
  34.     opts:=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
  35.     IF ReadArgs('FILE/A,S=SEARCH/K,SIZE/N,K/S,LINES/S,TO/K,R=RECURSIVE/S,QUIET/S,BUF=BUFFER/K/N,PARTS/S,NOCUT/S,QUICK/S,NOCASE/S,DOWILD/S,MAX/K/N',opts,rda)=NIL THEN Raise(ER_ARGS)
  36.  
  37.     IF CtrlC() THEN Raise(ER_BREAK)
  38.  
  39.     -> Open input file
  40.  
  41.     flen:=FileLength(opts[0])
  42.     IF flen<1 THEN Raise(ER_IO)
  43.     fhandle:=Open(opts[0],OLDFILE)
  44.     IF fhandle=NIL THEN Raise(ER_IO)
  45.  
  46.     -> Parse search STRING FOR \n\t etc, IF any
  47.  
  48.     IF opts[1] THEN parsestr(opts[1],search)
  49.  
  50.     IF (opts[1]=NIL) AND (opts[2]=NIL)
  51.         WriteF('Splat: required argument missing\n')
  52.         Raise(OK)
  53.         ENDIF
  54.  
  55.     size:=0 ; buflen:=0
  56.  
  57.     -> SET buffer size
  58.  
  59.     IF opts[8]
  60.         a:=opts[8]
  61.         buflen:=(^a)*1024
  62.         ENDIF
  63.  
  64.     -> SET block size, IF any
  65.  
  66.     IF opts[2]
  67.         a:=opts[2]
  68.         size:=^a
  69.         IF opts[3] THEN size:=size*1024
  70.         IF flen<=size THEN Raise(ER_LENGTH)
  71.         IF opts[4]
  72.             lines:=size
  73.             size:=flen
  74.             ENDIF
  75.         ENDIF
  76.  
  77.     -> IF keyword PARTS exists, calculate file size AND force RECURSIVE mode
  78.  
  79.     IF opts[9]
  80.         opts[6]:=1
  81.         size:=Div(flen,size)+1
  82.         ENDIF
  83.  
  84.     IF opts[14]
  85.         max:=opts[14]
  86.         max:=^max
  87.         IF max<2 THEN Raise(ER_ARGS)
  88.         ENDIF
  89.  
  90.     -> Allocate possibly SIZE bytes (OR specified buffer size), with an 8k buffer fallback
  91.  
  92.     IF buflen=0
  93.         IF opts[1] THEN buflen:=flen ELSE buflen:=size
  94.         ENDIF
  95.  
  96.     mem:=AllocMem(buflen,0)
  97.     IF mem=NIL
  98.         mem:=AllocMem(8192,0)
  99.         IF mem=NIL THEN Raise(ER_MEM)
  100.         buflen:=8192
  101.         ENDIF
  102.     IF opts[4] THEN size:=lines
  103.  
  104.     IF CtrlC() THEN Raise(ER_BREAK)
  105.  
  106.     -> Read the first buffer
  107.  
  108.     count:=Read(fhandle,mem,buflen)
  109.     IF count=-1 THEN Raise(ER_IO)
  110.     IF count=0 THEN eof:=TRUE
  111.     offset:=0
  112.  
  113.     -> Main LOOP
  114.  
  115.     a:=-1
  116.     eof:=0
  117.     sflag:=NIL
  118.     z:=search
  119.     REPEAT
  120.         IF opts[2] AND (opts[4]=0)
  121.             blockleft:=size
  122.             eob:=0
  123.             REPEAT
  124.                 IF (offset+blockleft<=buflen) OR (count<buflen)
  125.                     IF fout=NIL THEN fout:=opennext()
  126.                     IF (count<buflen) AND (count-offset<blockleft)
  127.                         blockleft:=count-offset
  128.                         eof:=TRUE
  129.                         ENDIF
  130.                     er:=Write(fout,mem+offset,blockleft)
  131.                     IF er=-1 THEN Raise(ER_IO)
  132.                     offset:=offset+blockleft
  133.                     eob:=TRUE
  134.                     IF offset=count
  135.                         count:=Read(fhandle,mem,buflen)
  136.                         IF count=-1 THEN Raise(ER_IO)
  137.                         IF count=0 THEN eof:=TRUE
  138.                         offset:=0
  139.                         ENDIF
  140.                 ELSE
  141.                     IF fout=NIL THEN fout:=opennext()
  142.                     er:=Write(fout,mem+offset,buflen-offset)
  143.                     IF er=-1 THEN Raise(ER_IO)
  144.                     blockleft:=blockleft-(buflen-offset)
  145.                     count:=Read(fhandle,mem,buflen)
  146.                     IF count=-1 THEN Raise(ER_IO)
  147.                     IF count=0 THEN eof:=TRUE
  148.                     offset:=0
  149.                     ENDIF
  150.                 IF CtrlC() THEN Raise(ER_BREAK)
  151.                 UNTIL eob OR eof
  152.             IF opts[6]=NIL THEN size:=flen
  153.             DEC max
  154.             IF max=1 THEN size:=flen
  155.         ELSEIF opts[4]
  156.             lines:=size
  157.             REPEAT
  158.                 IF offset>=count
  159.                     count:=Read(fhandle,mem,buflen)
  160.                     IF count=-1 THEN Raise(ER_IO)
  161.                     IF count=0 THEN eof:=TRUE
  162.                     offset:=0
  163.                     ENDIF
  164.                 IF eof=NIL
  165.                     MOVE.L mem,A0
  166.                     MOVE.L offset,D0
  167.                     MOVE.L lines,D1
  168. w2:                 CMPI.B #10,0(A0,D0.L)
  169.                     BEQ.S  x3
  170.                     CMP.L  count,D0
  171.                     BEQ.S  x2
  172. x4:                 ADDQ.L #1,D0
  173.                     BRA.S  w2
  174. x3:                 SUBQ.L #1,D1
  175.                     BNE.S  x4
  176. x2:                 MOVE.L D0,flag
  177.                     MOVE.L D1,lines
  178.                     IF flag<count THEN INC flag
  179.                     IF CtrlC() THEN Raise(ER_BREAK)
  180.                     IF fout=NIL THEN fout:=opennext()
  181.                     er:=Write(fout,mem+offset,flag-offset)
  182.                     IF er=-1 THEN Raise(ER_IO)
  183.                     offset:=flag
  184.                     ENDIF
  185.                 UNTIL (lines=0) OR eof
  186.                 IF opts[6]=NIL THEN size:=flen
  187.                 DEC max
  188.                 IF max=1 THEN size:=flen
  189.             ENDIF
  190.         IF opts[1]
  191.             REPEAT
  192.                 IF offset>=count
  193.                     count:=Read(fhandle,mem,buflen)
  194.                     IF count=-1 THEN Raise(ER_IO)
  195.                     IF count=0 THEN eof:=TRUE
  196.                     offset:=0
  197.                     ENDIF
  198.                 IF eof=NIL
  199.                     flag:=searchstr(mem,count,offset)
  200.                     IF sflag THEN flag:=count
  201.                     IF flag>count THEN DEC flag
  202.                     IF CtrlC() THEN Raise(ER_BREAK)
  203.                     IF fout=NIL THEN fout:=opennext()
  204.                     er:=Write(fout,mem+offset,flag-offset)
  205.                     IF er=-1 THEN Raise(ER_IO)
  206.                     offset:=flag
  207.                     ENDIF
  208.                 UNTIL (offset<count) OR eof
  209.             IF opts[6]=NIL THEN sflag:=TRUE
  210.             DEC max
  211.             IF max=1 THEN sflag:=TRUE
  212.             ENDIF
  213.         REPEAT
  214.             IF offset>=count
  215.                 count:=Read(fhandle,mem,buflen)
  216.                 IF count=-1 THEN Raise(ER_IO)
  217.                 IF count=0 THEN eof:=TRUE
  218.                 offset:=0
  219.                 ENDIF
  220.             IF opts[10] AND (eof=NIL)
  221.                 MOVE.L mem,A0
  222.                 MOVE.L offset,D0
  223. w:              CMPI.B #10,0(A0,D0.L)
  224.                 BEQ.S  x
  225.                 CMP.L  count,D0
  226.                 BEQ.S  x
  227.                 ADDQ.L #1,D0
  228.                 BRA.S  w
  229. x:              MOVE.L D0,flag
  230.                 INC flag
  231.                 er:=Write(fout,mem+offset,flag-offset)
  232.                 IF er=-1 THEN Raise(ER_IO)
  233.                 offset:=flag
  234.                 ENDIF
  235.             UNTIL (offset<count) OR eof
  236.         Close(fout) ; fout:=NIL
  237.         UNTIL eof
  238.     IF (opts[7]=NIL)
  239.         IF (opts[11]=NIL) THEN WriteF('\d files created.\n',a+1) ELSE WriteF('\d',a+1)
  240.         ENDIF
  241.  
  242. EXCEPT DO
  243.     IF fout THEN Close(fout)
  244.     IF mem THEN FreeMem(mem,buflen)
  245.     IF fhandle THEN Close(fhandle)
  246.     IF rda THEN FreeArgs(rda)
  247.     IF rda THEN FreeDosObject(DOS_RDARGS,rda)
  248.     IF exception
  249.         SELECT exception
  250.         CASE ER_MEM ; WriteF('Not enough memory.\n')
  251.         CASE ER_ARGS ; PrintFault(IoErr(),'Splat')
  252.         CASE ER_IO ; PrintFault(IoErr(),'Splat')
  253.         CASE ER_UNIMP ; WriteF('Function is not implemented yet.\n')
  254.         CASE ER_LENGTH ; WriteF('SIZE argument is bigger than file size.\n')
  255.         CASE ER_BREAK ; WriteF('***Break\n')
  256.         ENDSELECT
  257.         ENDIF
  258.     CleanUp()
  259. ENDPROC
  260.  
  261. PROC parsestr(str,b)
  262.     DEF a,ch,x
  263.  
  264.     a:=0 ; x:=0
  265.     REPEAT
  266.         ch:=str[a++]
  267.         IF (ch="?") AND opts[13] THEN ch:=255
  268.         IF ch="\\"
  269.             ch:=str[a++]
  270.             IF ch="n" THEN b[x++]:=10
  271.             IF ch="\\" THEN b[x++]:="\\"
  272.             IF ch="t" THEN b[x++]:=9
  273.             IF ch="?" THEN b[x++]:="?"
  274.         ELSE
  275.             b[x++]:=ch
  276.             ENDIF
  277.         UNTIL ch=0
  278.     SetStr(b,x)
  279. ENDPROC
  280.  
  281. PROC opennext()
  282.     DEF ext[5]:STRING,fout=NIL
  283.  
  284.     INC a
  285.     StrCopy(name,'NULL')
  286.     IF opts[5]
  287.         StrCopy(name,opts[5])
  288.         IF (name[EstrLen(name)-1]="/") OR (name[EstrLen(name)-1]=":") THEN StrAdd(name,FilePart(opts[0]))
  289.     ELSE
  290.         StrCopy(name,opts[0])
  291.     ENDIF
  292.  
  293.     StringF(ext,'.\d',a)
  294.     StrAdd(name,ext)
  295.  
  296.     fout:=Open(name,NEWFILE)
  297.     IF fout=NIL THEN Raise(ER_IO)
  298. ENDPROC fout
  299.  
  300. PROC searchstr(buf,bufsize,offset)
  301.     bufsize:=buf+bufsize
  302.     offset:=buf+offset
  303.     IF opts[12]=NIL
  304.         MOVE.L offset,A1
  305.         MOVE.L bufsize,D2
  306.         MOVEQ  #0,D0
  307.         MOVE.L z,A0
  308. nx:     MOVE.B (A0)+,D0
  309.         BEQ.S  ex
  310.         BPL.S  zz
  311.         ADDQ.L #1,A1
  312.         CMP.L  A1,D2
  313.         BEQ.S  ex
  314.         BRA.S  nx
  315. zz:     CMP.L  A1,D2
  316.         BEQ.S  ex
  317.         CMP.B  (A1)+,D0
  318.         BEQ.S  nx
  319.         MOVE.L search,A0
  320.         BRA.S  nx
  321. ex:     MOVE.L A1,offset
  322.         MOVE.L A0,z
  323.         DEC z
  324.         IF (^z)=0 THEN z:=search
  325.     ELSE
  326.         UpperStr(search)
  327.  
  328.         MOVE.L offset,A1
  329.         MOVE.L bufsize,D2
  330.         MOVEQ  #0,D0
  331.         MOVEQ  #0,D1
  332.         MOVE.L z,A0
  333. nx2:    MOVE.B (A0)+,D0
  334.         BEQ.S  ex2
  335.         BPL.S  zz2
  336.         ADDQ.L #1,A1
  337.         CMP.L  A1,D2
  338.         BEQ.S  ex2
  339.         BRA.S  nx2
  340. zz2:    CMP.L  A1,D2
  341.         BEQ.S  ex2
  342.         MOVE.B (A1)+,D1
  343.         BCLR   #5,D1
  344.         CMP.B  D0,D1
  345.         BEQ.S  nx2
  346.         MOVE.L search,A0
  347.         BRA.S  nx2
  348. ex2:    MOVE.L A1,offset
  349.         MOVE.L A0,z
  350.         DEC z
  351.         IF (^z)=0 THEN z:=search
  352.         ENDIF
  353. ENDPROC offset-buf
  354.